package com.platform.common.entity;

import cn.hutool.core.util.StrUtil;
import com.platform.common.constant.RespConstant;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.List;

/**
 * 统一的返回数据
 * @author: yuanlai
 * @description: api请求返回类
 * @time: 2020/11/17 12:25
 */
@Data
@NoArgsConstructor
public class ApiResponse<T> implements Serializable {
    private static final long serialVersionUID = -1362870120869005971L;
    @ApiModelProperty("返回编码,000000为成功")
    private String code;
    @ApiModelProperty("返回信息")
    private String message;
    @ApiModelProperty("返回对象")
    private T data;

    public boolean success() {
        return this.code.equals(RespConstant.SUCCESS.getCode());
    }

    /**
     * 成功返回,使用默认信息
     *
     * @return
     */
    public static <T> ApiResponse<T> ok() {
        return ok(null);
    }

    /**
     * 成功返回,使用默认信息
     *
     * @param data 返回数据
     * @return
     */
    public static <T> ApiResponse<T> ok(T data) {
        return ok(RespConstant.SUCCESS.getMessage(), data);
    }

    /**
     * 成功返回,使用默认编码
     *
     * @param message 信息
     * @param data    返回数据
     * @return
     */
    public static <T> ApiResponse<T> ok(String message, T data) {
        return getInstance(RespConstant.SUCCESS.getCode(), message, data);
    }

    /**
     * 错误返回,默认编码:999999,默认信息:系统异常
     *
     * @return
     */
    public static <T> ApiResponse<T> fail() {
        return fail(RespConstant.SYS_ERROR.getMessage());
    }

    /**
     * 错误返回,默认编码999999
     *
     * @param message 错误信息
     * @return
     */
    public static <T> ApiResponse<T> fail(String message) {
        return fail(RespConstant.SYS_ERROR.getCode(), message);
    }

    /**
     * 错误返回
     *
     * @param apiResponseCode 错误信息对象
     * @return
     */
    public static <T> ApiResponse<T> fail(ApiResponseCode apiResponseCode) {
        return fail(apiResponseCode.getCode(), apiResponseCode.getMessage());
    }

    /**
     * 错误返回
     *
     * @param apiResponse
     * @return
     */
    public static <T> ApiResponse<T> fail(ApiResponse<T> apiResponse) {
        return fail(apiResponse.getCode(), apiResponse.getMessage());
    }

    /**
     * 错误返回
     *
     * @param code    编码
     * @param message 错误信息
     * @return
     */
    public static <T> ApiResponse<T> fail(String code, String message) {
        return fail(code, message, null);
    }

    /**
     * 错误返回
     *
     * @param apiResponseCode 错误信息对象
     * @param data            数据
     * @param <T>
     * @return
     */
    public static <T> ApiResponse<T> fail(ApiResponseCode apiResponseCode, T data) {
        return fail(apiResponseCode.getCode(), apiResponseCode.getMessage(), data);
    }

    /**
     * 错误返回
     *
     * @param code    编码
     * @param message 错误信息
     * @param data    数据
     * @param <T>
     * @return
     */
    public static <T> ApiResponse<T> fail(String code, String message, T data) {
        return getInstance(code, message, data);
    }

    public static <T> ApiResponse<T> fail(ApiResponseCode responseCode, String... paramValues) {
        return getInstance(responseCode.getCode(), responseCode.getMessage(), paramValues);
    }

    /**
     * 成功返回,使用默认编码
     *
     * @return
     */
    public static <T extends Serializable> ApiResponse<ApiPageResponse<T>> page(long pageNumber, long pageSize,
                                                                                long totalCount, List<T> items) {
        return getInstance(RespConstant.SUCCESS, ApiPageResponse.getInstance(pageNumber, pageSize, totalCount, items));
    }


    private static <T> ApiResponse<T> getInstance(ApiResponseCode responseCode, T data) {
        return new ApiResponse<>(responseCode.getCode(), responseCode.getMessage(), data);
    }

    private static <T> ApiResponse<T> getInstance(String code, String message, T data) {
        return new ApiResponse<>(code, message, data);
    }

    private static <T> ApiResponse<T> getInstance(String code, String message, String... paramValues) {
        return new ApiResponse<>(code, StrUtil.format(message, paramValues), null);
    }

    protected ApiResponse(String code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }
}
